package com.rpframework.utils;

import com.squareup.okhttp.*;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.rpframework.utils.URLUtils.toQueryString;

public class OkHttpUtil {
    private static final OkHttpClient mOkHttpClient = new OkHttpClient();

    static {
        mOkHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
    }

    /**
     * 该不会开启异步线程。
     */
    public static Response execute(Request request) throws IOException {
        return mOkHttpClient.newCall(request).execute();
    }

    /**
     * 开启异步线程访问网络
     */
    public static void enqueue(Request request, Callback responseCallback) {
        mOkHttpClient.newCall(request).enqueue(responseCallback);
    }

    /**
     * 开启异步线程访问网络, 且不在意返回结果（实现空callback）
     */
    public static void enqueue(Request request) {
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(Response arg0) throws IOException {
            }

            @Override
            public void onFailure(Request arg0, IOException arg1) {
            }
        });
    }

    public static String getStringFromServer(String url) throws IOException {
        Request request = new Request.Builder().url(url).build();
        Response response = execute(request);
        if (response.isSuccessful()) {
            return response.body().string();
        } else {
            throw new IOException("Unexpected code " + response);
        }
    }

    private static final String CHARSET_NAME = "UTF-8";

    /**
     * 这里使用了Http的API。只是为了方便
     */
    private static String formatParams(List<BasicNameValuePair> params) {
        return URLEncodedUtils.format(params, CHARSET_NAME);
    }

    /**
     * 为HttpGet 的 url 方便的添加多个name value 参数。
     */
    public static String attachHttpGetParams(String url, List<BasicNameValuePair> params) {
        return url + "?" + formatParams(params);
    }

    /**
     * 为HttpGet 的 url 方便的添加1个name value 参数。
     */
    public static String attachHttpGetParam(String url, String name, String value) {
        return url + "?" + name + "=" + value;
    }

    /**
     * 发送POST数据
     */
    public static String post(String url, List<BasicNameValuePair> params) throws IOException {
        FormEncodingBuilder formEncodingBuilder = new FormEncodingBuilder();
        for (BasicNameValuePair basicNameValuePair : params) {
            formEncodingBuilder.add(basicNameValuePair.getName(), basicNameValuePair.getValue());
        }
        RequestBody formBody = formEncodingBuilder.build();

        Request request = new Request.Builder().url(url).post(formBody).build();

        Response response = mOkHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            return response.body().string();
        } else {
            throw new IOException("Unexpected code " + response);
        }
    }

    /**
     * get请求数据
     */
    public static String get(String url, List<BasicNameValuePair> params) {
        return get(url, parse(params));
    }

    /**
     * {@Link}get(String,List<BasicNameValuePair>) +无参
     */
    public static String get(String url) {
        return get(url,new ArrayList<>());
    }

    /**
     * get请求数据
     */
    public static String get(String url, Map<String, Object> params) {
        Request request;
        try {
            request = new Request.Builder().url(url + "?" + toQueryString(params)).get().build();
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        Response response;
        try {
            response = mOkHttpClient.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                throw new IOException("Unexpected code " + response);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * {@Link}post(String,List<BasicNameValuePair>) +参数转换
     */
    public static String post(String url, Map<String, Object> params) {
        try {
            return post(url, parse(params));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static List<BasicNameValuePair> parse(Map<String, Object> params) {
        return params.entrySet().stream().map(e -> new BasicNameValuePair(e.getKey(), e.getValue().toString())).collect(Collectors.toList());
    }

    public static Map<String, Object> parse(List<BasicNameValuePair> params) {
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        if (!CollectionUtils.isEmpty(params)) {
            for (BasicNameValuePair p : params) {
                map.put(p.getName(), p.getValue());
            }
        }
        return map;
    }
}